[org 0x500]        ; setup 程序加载到 0x7E00
[bits 16]

    jmp start      ; 需要跳到代码段，否则找不到

gdt_start:
    ; 空描述符（必需）
    dd 0x0
    dd 0x0

    ; 代码段描述符（Type=0x9A, 基址=0x0, 界限=0xFFFFF, DPL=0）
    dw 0xFFFF      ; 段界限低16位
    dw 0x0         ; 段基址低16位
    db 0x0         ; 段基址中8位
    db 10011010b   ; 访问字节（P=1, DPL=00, S=1, Type=1010）
    db 11001111b   ; 标志（G=1, D/B=1, AVL=0, 段界限高4位）
    db 0x0         ; 段基址高8位

    ; 数据段描述符（Type=0x92, 基址=0x0, 界限=0xFFFFF, DPL=0）
    dw 0xFFFF
    dw 0x0
    db 0x0
    db 10010010b   ; 类型改为 10010010b（数据段）
    db 11001111b
    db 0x0

gdt_end:

; GDT 描述符（用于 lgdt 指令）
gdt_descriptor:
    dw gdt_end - gdt_start - 1  ; GDT 大小（16位）
    dd gdt_start                 ; GDT 基地址（32位）

start:
    xchg bx, bx
    mov si, msg_setup
    call print_string

    xchg bx, bx
    cli
    lgdt [gdt_descriptor]  ; 加载 GDT
    mov al, 0xDD           ; 启用 A20
    out 0x64, al
    mov eax, cr0
    or  eax, 0x1
    mov cr0, eax
    jmp 0x08:protected_mode  ; 远跳转刷新流水线

print_string:
    mov ah, 0x0E
    mov bh, 0x00
.next_char:
    lodsb
    test al, al
    jz .done
    int 0x10
    jmp .next_char
.done:
    ret

    msg_setup db 'Ready into protected!', 0x0D, 0x0A, 0



[bits 32]
protected_mode:
;    xchg bx, bx
    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov ss, ax

    jmp $
;    mov esp, 0x90000
    ; 进入保护模式后的代码...